package com.actionpals.net
{
	import com.actionpals.text.AdvancedStyleSheet;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.text.StyleSheet;
	
	/**
	 * Dispatched when the download operation commences following a call to the StyleLoader.load() method.
	 */
	[Event( name="open", type="flash.events.Event.OPEN" )]
	
	/**
	 * Dispatched when data is received as the download operation progresses following a call to the StyleLoader.load() method.
	 */
	[Event( name="progress", type="flash.events.ProgressEvent.PROGRESS" )]
	
	/**
	 * Dispatched after an external CSS file has loaded successfully following a call to the StyleLoader.load() method.
	 */
	[Event( name="complete", type="flash.events.Event.COMPLETE" )]
	
	/**
	 * Dispatched after an external CSS file or CSS content in a CSS string has parsed successfully.
	 */
	[Event( name="init", type="flash.events.Event.INIT" )]
	
	/**
	 * Dispatched if a call to StyleLoader.load() attempts to access data over HTTP.
	 */
	[Event( name="httpStatus", type="flash.events.HTTPStatusEvent.HTTP_STATUS" )]
	
	/**
	 * Dispatched if a call to StyleLoader.load() results in a fatal error that terminates the download.
	 */
	[Event( name="ioError", type="flash.events.IOErrorEvent.IO_ERROR" )]
	
	/**
	 * Dispatched if a call to StyleLoader.load() attempts to load data from a server outside the security sandbox.
	 */
	[Event( name="securityError", type="flash.events.SecurityErrorEvent.SECURITY_ERROR" )]
	
	
	/**
	 * The StyleLoader class handles loading and parsing CSS content either from an external CSS file or from CSS content in a CSS string.
	 * 
	 * @author Mark Walters
	 * 
	 * <p>Flash Player supports a subset of properties in the original CSS1 specification (<a href="http://www.w3.org/TR/REC-CSS1" target="external">www.w3.org/TR/REC-CSS1</a>). 
	 * The following table shows the supported Cascading Style Sheet (CSS) properties and values, as well as their corresponding ActionScript property names. 
	 * (For the added properties supported by the AdvancedStyleSheet parser see the AdvancedStyleSheet documentation.) 
	 * (Each ActionScript property name is derived from the corresponding CSS property name; if the name contains a hyphen, the hyphen is omitted and the subsequent character is capitalized.)</p>
	 * <table class="innertable" >
	 * <tr>
	 * <th>CSS property</th>
	 * <th>ActionScript property</th>
	 * <th>Usage and supported values</th>
	 * </tr>
	 * <tr>
	 * <td><code>color</code></td>
	 * <td><code>color</code></td>
	 * <td>Only hexadecimal color values are supported. 
	 * Named colors (such as <code>blue</code>) are not supported. 
	 * Colors are written in the following format: <code>#FF0000</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>display</code></td>
	 * <td><code>display</code></td>
	 * <td>Supported values are <code>inline</code>, <code>block</code>, and <code>none</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>font-family</code></td>
	 * <td><code>fontFamily</code></td>
	 * <td>A comma-separated list of fonts to use, in descending order of desirability. 
	 * Any font family name can be used. 
	 * If you specify a generic font name, it is converted to an appropriate device font. 
	 * The following font conversions are available: <code>mono</code> is converted to <code>_typewriter</code>, <code>sans-serif</code> is converted to <code>_sans</code>, and <code>serif</code> is converted to <code>_serif</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>font-size</code></td>
	 * <td><code>fontSize</code></td>
	 * <td>Only the numeric part of the value is used. 
	 * Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * <tr>
	 * <td><code>font-style</code></td>
	 * <td><code>fontStyle</code></td>
	 * <td>Recognized values are <code>normal</code> and <code>italic</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>font-weight</code></td>
	 * <td><code>fontWeight</code></td>
	 * <td>Recognized values are <code>normal</code> and <code>bold</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>kerning</code></td>
	 * <td><code>kerning</code></td>
	 * <td>Recognized values are <code>true</code> and <code>false</code>. 
	 * Kerning is supported for embedded fonts only. Certain fonts, such as Courier New, do not support kerning. 
	 * The kerning property is only supported in SWF files created in Windows, not in SWF files created on the Macintosh. 
	 * However, these SWF files can be played in non-Windows versions of Flash Player and the kerning still applies.</td>
	 * </tr>
	 * <tr>
	 * <td><code>leading</code></td>
	 * <td><code>leading</code></td>
	 * <td>The amount of space that is uniformly distributed between lines. 
	 * The value specifies the number of pixels that are added after each line. 
	 * A negative value condenses the space between lines. 
	 * Only the numeric part of the value is used. Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * <tr>
	 * <td><code>letter-spacing</code></td>
	 * <td><code>letterSpacing</code></td>
	 * <td>The amount of space that is uniformly distributed between characters. 
	 * The value specifies the number of pixels that are added after each character. 
	 * A negative value condenses the space between characters. 
	 * Only the numeric part of the value is used. 
	 * Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * <tr>
	 * <td><code>margin-left</code></td>
	 * <td><code>marginLeft</code></td>
	 * <td>Only the numeric part of the value is used. Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * <tr>
	 * <td><code>margin-right</code></td>
	 * <td><code>marginRight</code></td>
	 * <td>Only the numeric part of the value is used. 
	 * Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * <tr>
	 * <td><code>text-align</code></td>
	 * <td><code>textAlign</code></td>
	 * <td>Recognized values are <code>left</code>, <code>center</code>, <code>right</code>, and <code>justify</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>text-decoration</code></td>
	 * <td><code>textDecoration</code></td>
	 * <td>Recognized values are <code>none</code> and <code>underline</code>.</td>
	 * </tr>
	 * <tr>
	 * <td><code>text-indent</code></td>
	 * <td><code>textIndent</code></td>
	 * <td>Only the numeric part of the value is used. 
	 * Units (px, pt) are not parsed; pixels and points are equivalent.</td>
	 * </tr>
	 * </table>
	 */
	public class StyleLoader extends EventDispatcher
	{
		/**
		 * @private
		 */
		protected var _styleSheet:StyleSheet;
		
		/**
		 * Constructor.
		 */		
		public function StyleLoader()
		{
			super();
		}
		
		/**
		 * Loads the StyleLoader object with data from the site specified by the request parameter.
		 * This method initiates an operation that always completes asynchronously.
		 * When loading and parsing of the CSS content from the request parameter is complete, the complete event is dispatched.
		 * 
		 * @param request A URLRequest object specifying the URL to download.
		 * @param useAdvancedParser Whether the CSS content should be parsed with the AdvancedStyleSheet parser. Default is false.
		 * 			AdvancedStyleSheet extends the CSS parsing capabilities of Flash.
		 * 			(For the added properties supported by the AdvancedStyleSheet parser see the AdvancedStyleSheet documentation.)
		 * 			This should only be used if the CSS content is using properties not supported in the Flash Player.
		 */		
		public function load( request:URLRequest, useAdvancedParser:Boolean=false ):void
		{
			_styleSheet = useAdvancedParser ? new AdvancedStyleSheet() : new StyleSheet();
			
			var loader:URLLoader = new URLLoader();
			loader.addEventListener( Event.OPEN, onEvent );
			loader.addEventListener( ProgressEvent.PROGRESS, onEvent );
			loader.addEventListener( Event.COMPLETE, onComplete );
			loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, onEvent );
			loader.addEventListener( IOErrorEvent.IO_ERROR, onEvent );
			loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onEvent );
			loader.load( request );
		}
		
		/**
		 * Loads the StyleLoader object with the CSS content contained in the CSS string.
		 * When parsing of the CSS content is complete, the complete event is dispatched.
		 * The complete event is always dispatched asynchronously.
		 * 
		 * @param cssContent The CSS content to parse.
		 * @param useAdvancedParser Whether the CSS content should be parsed with the AdvancedStyleSheet parser. Default is false.
		 * 			AdvancedStyleSheet extends the CSS parsing capabilities of Flash.
		 * 			(For the added properties supported by the AdvancedStyleSheet parser see the AdvancedStyleSheet documentation.)
		 * 			This should only be used if the CSS content is using properties not supported in the Flash Player.
		 */		
		public function loadString( cssContent:String, useAdvancedParser:Boolean=false ):void
		{
			_styleSheet = useAdvancedParser ? new AdvancedStyleSheet() : new StyleSheet();
			
			parseCSS( cssContent );
		}
		
		/**
		 * The StyleSheet created from parsing the CSS content received from the load or loadString operation.
		 * This property is populated only when the load operation is complete.
		 * 
		 * @return StyleSheet
		 */		
		public function get styleSheet():StyleSheet
		{
			return _styleSheet;
		}
		
		/**
		 * @private
		 */
		protected function parseCSS( cssContent:String ):void
		{
			_styleSheet.parseCSS( cssContent );
			dispatchEvent( new Event( Event.INIT ) );
		}
		
		
		/**
		 * @private
		 */
		protected function onComplete( evt:Event ):void
		{
			parseCSS( URLLoader( evt.target ).data );
			dispatchEvent( evt );
		}
		
		/**
		 * @private
		 */
		protected function onEvent( evt:Event ):void
		{
			dispatchEvent( evt );
		}
		
	}
}